#ifndef DATACENTER_H
#define DATACENTER_H

#include <QWidget>
#include "data.h"

#include "../network/netclient.h"

namespace model
{

class DataCenter : public QObject
{
    Q_OBJECT
public:
    static DataCenter* getInstance();
    ~DataCenter();

private:
    DataCenter();

    static DataCenter* instance;

    // 登录会话id
    // 这个信息是登录成功后, 服务器返回的.
    // 返回之后这个数据需要被客⼾端持久化保存在⽂件中.
    // 后续每次启动, 都从⽂件中拿到这个内容.
    // 当⽤⼾显式点击 "退出登录", 则删除这个信息

    //列出DataCenter所要管理的所有数据

    //当前客户端登录会话ID
    QString loginSessionId = "";

    //当前的用户信息
    UserInfo* myself = nullptr;

    //好友列表
    QList<UserInfo>* friendList = nullptr;

    //会话列表
    QList<ChatSessionInfo>* chatSessionList = nullptr;

    //当前会话ID
    QString currentChatSessionId = "";

    //记录每个会话中，都有哪些成员  key为chatSessionId value为成员
    QHash<QString,QList<UserInfo>>* memberList = nullptr;

    //待处理的好友申请列表
    QList<UserInfo>* applyList = nullptr;

    //每个会话中的最近消息列表,key为chatSessionId value为消息列表
    QHash<QString,QList<Message>>* recentMessages = nullptr;

    //存储每个会话，未读消息的个数
    QHash<QString,int>* unreadMessageCount = nullptr;

    //用户的好友搜索结果
    QList<UserInfo>* searchUserInfoResult = nullptr;

    //用户的消息搜索结果
    QList<Message>* searchMessageResult = nullptr;

    //短信验证码ID
    QString currentVerifyCodeId = "";

    //让 DataCenter 持有客户端的实例
    network::NetClient netClient;


public:
    void initWebsocket();
    //初始化数据文件
    void initDataFile();
    //持久化文件
    void saveDataFile();
    //加载文件到内存中
    void loadDataFile();
    //清空未读消息的数目
    void clearUnread(const QString& chatSessionId);
    //添加未读消息的数目
    void addUnread(const QString& chatSessionId);
    //获取未读消息的数目
    int getUnread(const QString& chatSessionId);

    //获取到当前的会话ID
    const QString& getLoginSessionId() const {
        return loginSessionId;
    }

    void ping() { netClient.ping(); }

    // 获取用户的个人信息
    void getMyselfAsync();
    UserInfo* getMyself();
    void resetMyself(std::shared_ptr<lch_im::GetUserInfoRsp> resp);

    // 获取好友列表
    void getFriendListAsync();
    QList<UserInfo>* getFriendList();
    void resetFriendList(std::shared_ptr<lch_im::GetFriendListRsp> resp);

    // 获取会话列表
    void getChatSessionListAsync();
    QList<ChatSessionInfo>* getChatSessionList();
    void resetChatSessionList(std::shared_ptr<lch_im::GetChatSessionListRsp> resp);

    // 获取好友申请列表
    void getApplyListAsync();
    QList<UserInfo>* getApplyList();
    void resetApplyList(std::shared_ptr<lch_im::GetPendingFriendEventListRsp> resp);

    // 获取最近几条消息
    void getRecentMessageListAsync(const QString& chatSessionId, bool updateUI);
    QList<Message>* getRecentMessageList(const QString& chatSessionId);
    void resetRecentMessageList(const QString& chatSessionId, std::shared_ptr<lch_im::GetRecentMsgRsp> resp);

    // 通过用户id去找到对应的会话列表
    ChatSessionInfo* findChatSessionByUserId(const QString& userId);
    // 根据会话 id 查询会话信息
    ChatSessionInfo* findChatSessionById(const QString& chatSessionId);

    // 将对应的会话放到第一个上面
    void topChatSessionInfo(const ChatSessionInfo& chatSessionInfo);

    void setCurrentChatSessionId(const QString& chatSessionId);
    const QString& getCurrentChatSessionId();

    void sendTextMessageAsync(const QString& chatSessionId,const QString& content);
    void sendImageMessageAsync(const QString& chatSessionId, const QByteArray& content);
    void sendFileMessageAsync(const QString& chatSessionId,const QString& filename,const QByteArray& content);
    void sendSpeechMessageAsync(const QString& chatSessionId,const QByteArray& speechContent);

    // 添加消息
    void addMessage(const Message& message);

    // 修改用户昵称
    void changeNicknameAsync(const QString& nickname);
    void resetNickname(const QString& nickname);

    // 修改用户签名
    void changeDescriptionAsync(const QString& desc);
    void resetDescription(const QString& desc);

    // 获取短信验证码
    void getVerifyCodeAsync(const QString& phone);
    void resetVerifyCodeId(const QString& verifyCodeId);
    const QString& getVerifyCodeId();

    // 修改头像
    void changeAvatarAsync(const QByteArray& imageBytes);
    void resetAvatar(const QByteArray& avatar);

    // 修改手机号
    void changePhoneAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
    void resetPhone(const QString& phone);

    // 通过好友ID找到对应的好友
    UserInfo* findFriendById(const QString& userId);

    // 删除好友
    void removeFriend(const QString& userId);
    void deleteFriendAsync(const QString& userId);

    // 申请好友
    void addFriendApplyAsync(const QString& userId);

    // 同意好友申请
    void acceptFriendApplyAsync(const QString& userId);

    // 拒绝好友申请
    void rejectFriendApplyAsync(const QString& userId);

    // 从好友申请列表中删除
    UserInfo removeFromApplyList(const QString& userId);

    // 点击删除好友按钮
    void clickDeleteFriendAsync(const QString& userId);

    // 创建群聊
    void createGroupChatSessionAsync(const QList<QString>& userIdList);
    // 退出群聊
    void exitGroupChatSessionAsync(const QString& userId,const QString& chatSessionId);

    // 获取会话的成员列表
    void getMemberListAsync(const QString& chatSessionId);
    QList<UserInfo>* getMemberList(const QString& chatSessionId);
    void resetMemberList(const QString& chatSessionId, const QList<lch_im::UserInfo>& memberList);

    // 搜索好友
    void searchUserAsync(const QString& searchKey);
    QList<UserInfo>* getSearchUserResult();
    void resetSearchUserResult(const QList<lch_im::UserInfo>& userList);

    // 搜索历史消息
    void searchMessageAsync(const QString& searchKey);
    void searchMessageByTimeAsync(const QDateTime& begTime, const QDateTime& endTime);
    QList<Message>* getSearchMessageResult();
    void resetSearchMessageResult(const QList<lch_im::MessageInfo>& msgList);

    // 登录注册
    void userLoginAsync(const QString& username, const QString& password);
    void resetLoginSessionId(const QString& loginSessionId);
    void userRegisterAsync(const QString& username, const QString& password);
    void phoneLoginAsync(const QString& phone, const QString& verifyCode);
    void phoneRegisterAsync(const QString& phone, const QString& verifyCode);

    // 获取单个文件
    void getSingleFileAsync(const QString &fileId);

    // 语音转文字
    void speechConvertTextAsync(const QString& fileId,const QByteArray& content);


signals:
    // 自定义信号
    void getMyselfDone();
    // 获取当前好友列表
    void getFriendListDone();
    // 获取会话列表
    void getChatSessionListDone();
    // 获取好友申请列表
    void getApplyListDone();
    // 修改头像
    void changeAvatarDone();
    // 删除好友完成
    void deleteFriendDone();
    // 清空当前会话
    void clearCurrentSession();
    // 获取最近几条消息
    void getRecentMessageListDone(const QString& chatSessionId);
    // 发送消息
    void sendMessageDone(MessageType messageType,const QByteArray& content,const QString& extraInfo);
    // 更新最后一条信息
    void updateLastMessage(const QString& chatSessionId);
    // 获取最近的消息列表
    void getRecentMessageListDoneNoUI(const QString& chatSessionId);
    // 收到消息
    void receiveMessageDone(const Message& message);
    // 修改昵称
    void changeNicknameDone();
    // 修改签名
    void changeDescriptionDone();
    // 获取验证码
    void getVerifyCodeDone();
    // 修改手机号
    void changePhoneDone();
    // 申请好友
    void addFriendApplyDone();
    // 收到好友申请
    void receiveFriendApplyDone();
    // 同意好友申请
    void acceptFriendApplyDone();
    // 拒绝好友申请
    void rejectFriendApplyDone();
    // 收到好友处理结果推送通知
    void receiveFriendProcessDone(const QString& nickname, bool agree);
    // 创建群聊
    void createGroupChatSessionDone();
    // 创建群聊完成
    void receiveSessionCreateDone();
    // 获取会话中的成员列表
    void getMemberListDone(const QString& chatSessionId);
    // 搜索好友
    void searchUserDone();
    // 搜索历史消息
    void searchMessageDone();
    // 用户名登录
    void userLoginDone(bool ok, const QString& reason);
    // 用户名注册
    void userRegisterDone(bool ok, const QString& reason);
    // 手机号登录
    void phoneLoginDone(bool ok, const QString& reason);
    // 手机号注册
    void phoneRegisterDone(bool ok, const QString& reason);
    // 获取单个文件
    void getSingleFileDone(const QString& fileId, const QByteArray& fileContent);
    // 语言识别
    void speechConvertTextDone(const QString& fileId, const QString& text);
    // 退出群聊
    void exitGroupChatSessionDone();


};

} // end namespace
#endif // DATACENTER_H
